# 为了能更好地处理数值型数据，Pandas 提供了几种窗口函数，
# 比如移动函数（rolling）、扩展函数（expanding）和指数加权函数（ewm）。

import pandas as pd
import numpy as np

# rolling() 又称移动窗口函数，它可以与 mean、count、sum、median、std 等聚合函数一起使用。
# 为了使用方便，Pandas 为移动函数定义了专门的方法聚合方法，比如 rolling_mean()、rolling_count()、rolling_sum() 等。

# window	默认值为 1，表示窗口的大小，也就是观测值的数量，
# min_periods	表示窗口的最小观察值，默认与 window 的参数值相等。
# center	是否把中间值做为窗口标准，默认值为 False。

# 生成时间序列
df = pd.DataFrame(np.random.randn(8, 4), index=pd.date_range('12/1/2020', periods=8), columns=['A', 'B', 'C', 'D'])
print(df)
#                    A         B         C         D
# 2020-12-01 -0.202135 -0.214798  0.294877  0.415271
# 2020-12-02  0.218017 -0.946109  0.404710 -1.538817
# 2020-12-03  0.321891 -1.009601  0.273609  1.620069
# 2020-12-04 -1.602514 -0.502069  1.283001  0.015853
# 2020-12-05  0.291389  1.139138 -0.811829 -0.974156
# 2020-12-06  0.313207 -1.332146 -0.136734  0.569842
# 2020-12-07  0.012481  0.430096  1.362377  0.021484
# 2020-12-08  0.405224  1.571629 -1.126729  0.714502
# 每3个数求求一次均值
print(df.rolling(window=3).mean())
#                    A         B         C         D
# 2020-12-01       NaN       NaN       NaN       NaN
# 2020-12-02       NaN       NaN       NaN       NaN
# 2020-12-03  0.112591 -0.723503  0.324399  0.165508
# 2020-12-04 -0.354202 -0.819260  0.653773  0.032368
# 2020-12-05 -0.329744 -0.124177  0.248260  0.220589
# 2020-12-06 -0.332639 -0.231692  0.111479 -0.129487
# 2020-12-07  0.205692  0.079030  0.137938 -0.127610
# 2020-12-08  0.243637  0.223193  0.032972  0.435276
# window=3表示是每一列中依次紧邻的每 3 个数求一次均值。
# 当不满足 3 个数时，所求值均为 NaN 值，因此前两列的值为 NaN，直到第三行值才满足要求 window =3

# expanding() 又叫扩展窗口函数，扩展是指由序列的第一个元素开始，逐个向后计算元素的聚合值。
df = pd.DataFrame(np.random.randn(10, 4),
                  index=pd.date_range('1/1/2018', periods=10),
                  columns=['A', 'B', 'C', 'D'])
print(df.expanding(min_periods=3).mean())
#                    A         B         C         D
# 2018-01-01       NaN       NaN       NaN       NaN
# 2018-01-02       NaN       NaN       NaN       NaN
# 2018-01-03 -0.141642  0.375358 -0.138700 -0.360975
# 2018-01-04 -1.092730  0.390944  0.277879 -0.612000
# 2018-01-05 -0.685152  0.251669  0.553413 -0.587368
# 2018-01-06 -1.155084  0.375168  0.369738 -0.466349
# 2018-01-07 -0.762809  0.135932  0.281267 -0.752943
# 2018-01-08 -0.801428  0.140022  0.365450 -0.650715
# 2018-01-09 -0.911344  0.147898  0.305782 -0.498427
# 2018-01-10 -0.663736 -0.017780  0.363219 -0.611640
# 设置 min_periods=3，表示至少 3 个数求一次均值，计算方式为 (index0+index1+index2)/3，
# 而 index3 的计算方式是 (index0+index1+index2+index3)/3，依次类推。

# ewm（全称 Exponentially Weighted Moving）表示指数加权移动。
# ewn() 函数先会对序列元素做指数加权运算，其次计算加权后的均值。
# 该函数通过指定 com、span 或者 halflife 参数来实现指数加权移动。

df = pd.DataFrame(np.random.randn(10, 4),
                  index=pd.date_range('12/1/2020', periods=10),
                  columns=['A', 'B', 'C', 'D'])
# 设置com=0.5，先加权再求均值
print(df.ewm(com=0.5).mean())
#                    A         B         C         D
# 2020-12-01  0.867822  0.016557  0.801213  1.901466
# 2020-12-02  1.541786 -0.004738 -0.429152  0.028986
# 2020-12-03  1.241511  0.133578  0.175280  0.332570
# 2020-12-04  0.156899 -0.526962  0.439147 -0.204239
# 2020-12-05  0.387505  0.097599 -0.514455  0.063636
# 2020-12-06 -1.070347 -0.082654 -1.667936 -0.839823
# 2020-12-07 -1.547788  1.000997 -1.152678 -0.797170
# 2020-12-08 -0.485147  0.082894 -0.166651  0.654758
# 2020-12-09 -0.460414 -1.195171  0.394225  0.701874
# 2020-12-10 -0.407189 -0.499484  1.074220  0.890471